#include "../pch/pch.h"

class ParallelWork : public IParallelWork {

	class Work
		: public e::sys::IRunnable
	{
	private:
		volatile bool _isRunning;
		IWorkPtr _work;

	public:
		Work(const IWorkPtr& process):_isRunning(true),_work(process) {
			E_DBG2("Construct()");
			assert(_work);
		}

		~Work() {
			E_DBG2("Destruct()");
		}

	private:
		//////////////////////////////////////////////////////////////////////////
		// IRunnable
		void run() {
			if (_work->init()) {
				while (_isRunning) {
					if (!_work->cycle()) {
						break;
					}
				}
			}
			_work->destroy();
		}

		void onJoin() {
			_isRunning = false;
			_work->cancelWait();
		}
	};

private:
	IThreadPoolPtr _threadPool;

public:
	ParallelWork():_threadPool(IThreadPool::New()) {
		E_DBG2("Construct()");
	}

	~ParallelWork() {
		E_DBG2("Destruct()");
	}

private:
	//////////////////////////////////////////////////////////////////////////
	// IMultiThreadProcesser
	void submit(const IWorkPtr& work) {
		_threadPool->submit(e::sys::IRunnablePtr(new Work(work)));
	}
};

IParallelWorkPtr IParallelWork::New() {
	return IParallelWorkPtr(new ParallelWork);
}

